/*! 
 * jquery.ux.button - v 1.0.0 - http://jquery-ux.com/
 * Copyright (c) 2010 Michael Helgeson, Three Dub Media
 * Open Source MIT License - http://jquery-ux.com/license 
 */
// Created: 2009-09-21 
// Updated: 2010-02-24
// REQUIRES: jquery 1.4+

;(function( $ ){ // confine scope

$.ux( "button", { // Register the PLUGIN... and public methods...
	version: "1.0.0",
	expose: "value content checked", // + enable disable destroy
	defaults:{
		content: null, // {Sting} html content to append
		type: "button", // {String} input type (form submission & behavior)
		name: null, // {String} input name (form submission & groups)
		value: null, // {String} input value (form submission)
		checked: false, // {Boolean} sets the "checked" attribute of the inputs
		valueIsContent: false, // {Boolean} sync values with content
		// plugin classnames
		classroot: "ux-button"
		// ux-button-NW 
		// ux-button-N 
		// ux-button-NE
		// ux-button-W 
		// ux-button-C 
		// ux-button-E
		// ux-button-SW 
		// ux-button-S 
		// ux-button-SE
		// ux-button-inside 
		// ux-button-behind
		// ux-button-content
		// ux-button-disabled
		// ux-button-hover
		// ux-button-focus
		// ux-button-active
		// ux-button-checked
		},
	create: function( elem, opts ){
		var $elem = $( elem );
		// flip some things around
		if ( $elem.is("input") ){
			opts.type = elem.type;
			opts.input = elem;
			opts.value = opts.content = elem.value;
			$elem = $elem.wrap('<span/>').parent();
			elem = $elem[0];
			elem.className = opts.input.className; // copy over classes
			}
		// store args, extend the instance
		$.extend( this, { elem:elem, opts:opts, $elem:$( elem ) });
		// create the new artificial markup, bind events
		this.$markup = $( this.markup() )
			.bind( "mouseenter mouseleave mousedown mouseup selectstart", $.proxy( this, "handler") );
		// bind click to suppress when disabled
		this.$elem.bind("click", $.proxy( this, "handler") );
		// make the text unselectable
		if ( opts.type != "text" ){
			this.$markup[0].unselectable = "on"; // IE
			if ( this.$markup[0].style ) this.$markup[0].style.MozUserSelect = "none"; // FF
			}
		// make the masked input element...
		this.$input = $( opts.input || '<input type="'+( opts.type )+'" />' ).addClass( this.classify("hidden") )
			[ opts.type=="text" ? "appendTo" : "prependTo" ]( this.$markup.find("."+ this.classify("inside") ) )
			.bind("focus blur click", $.proxy( this, "handler") )
			.attr({ name:opts.name, checked:opts.checked });
		this.input = this.$input[0];	
		// find and store the content container...
		this.$content = this.$markup.find("."+ this.classify("content") );
		// populate the button content and value...
		this.content( opts.content || this.$elem.html() || "" );
		if ( opts.value != undefined ) this.value( opts.value );
		// insert the new markup
		this.$elem.html("").append( this.$markup );
	//	this.$input.triggerHandler("click");
		},
	destroy: function(){
		// unbind events, remove new element
		this.$input.unbind();
		this.$markup.unbind().remove();
		// restore element content
		this.$elem.unbind( "click", $.proxy( this, "handler") )
			.html( this.$content.html() );
		},
	disable: function( disabled ){
		this.input.blur();
		this.$input.attr("disabled", disabled );
		this.$elem.toggleClass( this.classify("disabled"), disabled );
		},
	methods: {
		content: function( html ){
			if ( this.disabled ) return; // suppress when disabled
			if ( html == undefined ) 
				return this.$content.html(); // get
			this.$content.html( html ); // set
			if ( this.opts.valueIsContent )
				this.$input.val( html ); // set
			},
		value: function( val ){
			if ( this.disabled ) return; // suppress when disabled
			if ( val == undefined ) 
				return this.$input.val(); // get
			this.$input.val( val ); // set
			if ( this.opts.valueIsContent )
				this.$content.html( val ); // set
			},	
		checked: function( bool ){
			if ( this.disabled ) return; // suppress when disabled
			if ( bool == undefined ) // get
				return this.input.checked;
			this.input.checked = !!bool; // set
			this.$input.triggerHandler("click"); // handle
			},
		handler: function( event ){
			if ( this.disabled ){ // suppress clicks when disabled
				if ( event.type == "click" ) 
					event.stopImmediatePropagation();
				return;
				}
			switch ( event.type ){
				case "focus":
					this.focused = true;
					this.$elem.addClass( this.classify("focus") );
					// if the event target is a text box
					if ( this.opts.type == "text" )
						this.$input.addClass( this.classify("text-input") );
					// propagate to container element
					$.event.handle.call( this.elem, event );
					return;
				case this.opts.type != "hidden" && "mouseenter":
					this.hovered = true;
					this.$elem.addClass( this.classify("hover") );
					return;
				case this.opts.type != "hidden" && "mousedown":
					this.pressed = true;
					this.$elem.addClass( this.classify("active") );
				case "selectstart": 	
					return ( this.opts.type == "text" );
				case this.hovered && "mouseleave": 
					this.$elem.removeClass( this.classify("hover") );
					this.hovered = false;
				case "mouseleave": 
					this.$elem.removeClass( this.classify("active") );
					this.pressed = false;
					break;
				case "blur":
					this.$elem.removeClass( this.classify("focus") );
					this.focused = false;
					// if the event target is a text box
					if ( this.opts.type == "text" )
						this.$input.removeClass(this.classify("text-input"));
					this.value( this.$input.val() );
					// propagate to container element
					$.event.handle.call( this.elem, event );
					break;
				case this.pressed && "mouseup": 
					this.$elem.removeClass( this.classify("active") );
					this.input.focus();
					break;	
				case event.currentTarget == this.elem && event.target != this.input && "click": 
					if ( this.opts.type == "radio" )
						this.input.checked = true;
					if ( this.opts.type == "checkbox" )	
						this.input.checked = !this.input.checked;
					// handle the click event on the internal input...
					$.event.trigger( event, null, this.input );
					break;
				case event.currentTarget == this.input && "click": 
					if ( this.opts.type == "radio" || this.opts.type == "checkbox" )
						this.$elem.toggleClass( this.classify("checked"), this.input.checked );
					// if the event target is a checked radio button
					if ( this.opts.type == "radio" && this.input.checked ){
						// handle unchecking previous item from same named group
						if ( this.ux.radios[ this.opts.name ] && this.ux.radios[ this.opts.name ] != this.input )
							//$.button.radios[ this.opts.name ].triggerHandler( event );
							$.event.handle.call( this.ux.radios[ this.opts.name ], event );
						// store this radio by name for next time
						this.ux.radios[ this.opts.name ] = this.input;
						}
					// manually trigger native "submit" functionality
					//if ( ( /submit/i ).test( this.opts.type ) && !event.isPropagationStopped() )
					//	this.input.click();
					break;
				
				}
			},
		markup: function(){
			return [
				'<table class="', this.classify(), '" cellpadding="0" cellspacing="0" border="0">',
					'<tr><td class="', this.classify("NW"), '"></td>',
						'<td class="', this.classify("N"), '"></td>',
						'<td class="', this.classify("NE"), '"></td>',
						'</tr>',
					'<tr><td class="', this.classify("W"), '"></td>',
						'<td class="', this.classify("C"), '">',
							'<div class="', this.classify("inside"), '">',
								'<div class="', this.classify("behind"), '"></div>',
								'<div class="', this.classify("content"), '"></div>',
								'</div>',
							'</td>',
						'<td class="', this.classify("E"), '"></td>',
						'</tr>',
					'<tr><td class="', this.classify("SW"), '"></td>',
						'<td class="', this.classify("S"), '"></td>',
						'<td class="', this.classify("SE"), '"></td>',
						'</tr>',	
					'</table>'
				].join("");
			}
		}
	});

// cache (by name) for checked radio inputs
$.ux.plugins.button.radios = {}; 

// create some custom settings
$.button("checkbox",{
	type: "checkbox",
	valueIsContent: true
	});
$.button("radio",{
	type: "radio",
	valueIsContent: true
	});

})( jQuery ); // secure the $ jQuery alias